#include <SDL/SDL.h>
#include "zone.h"
#include "video.h"
#include "draw.h"
#include <stdio.h>
bool ran=false;

word old256;
extern byte v_16x16[];
extern byte v_256x256[];
extern byte v_lvllayout[];

extern long v_screenposx, v_screenposy;
extern long FFFFF708, FFFFF70C;

word scrollflagBuf1, scrollflagBuf2, scrollflagBuf3;
long screenposxBuf1, screenposyBuf1;
long FFFFFF18, FFFFFF1C, FFFFFF20, FFFFFF24, FFFFFF28, FFFFFF2C;

extern word FFFFF7F0;

#define LONGTOWORD(val) ((val&0xFFFF0000)>>16)
#define SWAPWORD(val) (((val&0x00FF)<<8)+((val&0xFF00)>>8))

word flipx,flipy;

char newText[100];


#define SONIC_REVISION 0

void LoadTilesAsYouMove()
{

    word *linerenderField = &scrollflagBuf2; //FFFFFF32
    long *position = &FFFFFF18;
    word layoutIndex = 0x40;
    int nametable = 0x6000;
    LoadSurroundingTiles2(linerenderField, position, layoutIndex, nametable);

    linerenderField = &scrollflagBuf3; //FFFFFF34
    position = &FFFFFF20;
    sub_69F4(linerenderField, position, layoutIndex, nametable);

    /*if Revision=0
    else
    lea	($FFFFFF36).w,a2
    lea	($FFFFFF28).w,a3
    bsr.w	locj_6EA4
    endc
    */
        
    linerenderField = &scrollflagBuf1;     //FFFFFF30
    position = &screenposxBuf1;
    layoutIndex = 0;
    nametable = 0x4000;
    LoadSurroundingTiles(linerenderField, position, layoutIndex, nametable);
    
}

void LoadSurroundingTiles(word *linerenderField, long *position, word layoutIndex, int nametable)
{
    if (*linerenderField != 0)
    {
        byte aboveScreen = *linerenderField & 1;

        //clear bit 0
        *linerenderField = *linerenderField - aboveScreen;
       
        if (aboveScreen != 0)
        {
            int yIndexRAM = -0x10;
            int xIndexRAM = -0x10;
            word vramAddress = Calc_VRAM_Pos(position, yIndexRAM, xIndexRAM);

            //moveq	#-$10,d4
	    //moveq	#-$10,d5
            DrawTiles_LR(position, vramAddress, yIndexRAM, xIndexRAM, nametable, layoutIndex);
        }
        
        byte belowScreen = *linerenderField & 2;

        //clear bit 1
        *linerenderField = *linerenderField - belowScreen;
        
        if (belowScreen != 0)
        {
            int yIndexRAM = 0xE0;
            int xIndexRAM = -0x10;
            word vramAddress = Calc_VRAM_Pos(position, yIndexRAM, xIndexRAM);

            //moveq	#-$10,d4
	    //moveq	#-$10,d5
            DrawTiles_LR(position, vramAddress, yIndexRAM, xIndexRAM, nametable, layoutIndex);

        }
        
        byte leftScreen = *linerenderField & 4;

        //clear bit 2
        *linerenderField = *linerenderField - leftScreen;
       
        if (leftScreen != 0)
        {
            int yIndexRAM = -0x10;
            int xIndexRAM = -0x10;
            word vramAddress = Calc_VRAM_Pos(position, yIndexRAM, xIndexRAM);

            //moveq	#-$10,d4
	    //moveq	#-$10,d5
            DrawTiles_TB(position, vramAddress, yIndexRAM, xIndexRAM, nametable, layoutIndex);
        }
        
        byte rightScreen = *linerenderField & 8;

        //clear bit 3
        *linerenderField = *linerenderField - rightScreen;
        
        if (rightScreen != 0)
        {
            int yIndexRAM = -0x10;
            int xIndexRAM = 0x140;
            word vramAddress = Calc_VRAM_Pos(position, yIndexRAM, xIndexRAM);

            //moveq	#-$10,d4
	    //moveq	#-$10,d5

            DrawTiles_TB(position, vramAddress, yIndexRAM, xIndexRAM, nametable, layoutIndex);
        }
    }
}
void LoadSurroundingTiles2(word *linerenderField, long *position, word layoutIndex, int nametable)
{
    if (*linerenderField != 0)
    {
        byte aboveScreen = *linerenderField & 1;

        //clear bit 0
        *linerenderField = *linerenderField - aboveScreen;
       
        if (aboveScreen != 0)
        {
            int yIndexRAM = -0x10;
            int xIndexRAM = -0x10;
            word vramAddress = Calc_VRAM_Pos(position, yIndexRAM, xIndexRAM);

            //moveq	#-$10,d4
	    //moveq	#-$10,d5

            #if SONIC_REVISION==0
            long numBlocks = 31;
            DrawTiles_LR_2(position, vramAddress, yIndexRAM, xIndexRAM, numBlocks, nametable, layoutIndex);
            #else
            DrawTiles_LR(position, vramAddress, yIndexRAM, xIndexRAM, nametable, layoutIndex);
            #endif
        }
        
        byte belowScreen = *linerenderField & 2;

        //clear bit 1
        *linerenderField = *linerenderField - belowScreen;
        
        if (belowScreen != 0)
        {
            int yIndexRAM = 0xE0;
            int xIndexRAM = -0x10;
            word vramAddress = Calc_VRAM_Pos(position, yIndexRAM, xIndexRAM);

            //moveq	#-$10,d4
	    //moveq	#-$10,d5

            #if SONIC_REVISION==0
            long numBlocks = 31;
            DrawTiles_LR_2(position, vramAddress, yIndexRAM, xIndexRAM, numBlocks, nametable, layoutIndex);
            #else
            DrawTiles_LR(position, vramAddress, yIndexRAM, xIndexRAM, nametable, layoutIndex);
            #endif
        }
        
        byte leftScreen = *linerenderField & 4;

        //clear bit 2
        *linerenderField = *linerenderField - leftScreen;
       
        #if SONIC_REVISION==0
        if (leftScreen != 0)
        {
            int yIndexRAM = -0x10;
            int xIndexRAM = -0x10;
            word vramAddress = Calc_VRAM_Pos(position, yIndexRAM, xIndexRAM);

            //moveq	#-$10,d4
	    //moveq	#-$10,d5

            
            signed short numPixels = FFFFF7F0 - (LONGTOWORD(position[1]) & -0x10);
            if (numPixels > 0)
            {
                word numBlocks = numPixels / 16;
                if (numBlocks > 15) { numBlocks = 15; }
                DrawTiles_TB_2(position, vramAddress, yIndexRAM, xIndexRAM, numBlocks, nametable, layoutIndex);
            }
        }
        
        byte rightScreen = *linerenderField & 8;

        //clear bit 3
        *linerenderField = *linerenderField - rightScreen;
        
        if (rightScreen != 0)
        {
            int yIndexRAM = -0x10;
            int xIndexRAM = 0x140;
            word vramAddress = Calc_VRAM_Pos(position, yIndexRAM, xIndexRAM);

            //moveq	#-$10,d4
	    //moveq	#-$10,d5

            
            word numPixels = FFFFF7F0 - (LONGTOWORD(position[1]) & -0x10);
            if (numPixels > 0)
            {
                word numBlocks = numPixels / 16;
                if (numBlocks > 15) { numBlocks = 15; }
                DrawTiles_TB_2(position, vramAddress, yIndexRAM, xIndexRAM, numBlocks, nametable, layoutIndex);
            }
        }
        #else
            if (leftScreen != 0)
            {
                int yIndexRAM = -0x10;
                int xIndexRAM = -0x10;
                word vramAddress = Calc_VRAM_Pos(position, yIndexRAM, xIndexRAM);

                //moveq	#-$10,d4
	        //moveq	#-$10,d5
                DrawTiles_TB(position, vramAddress, yIndexRAM, xIndexRAM, nametable, layoutIndex);
            }
            
            byte rightScreen = *linerenderField & 8;

            //clear bit 3
            *linerenderField = *linerenderField - rightScreen;
        
            if (rightScreen != 0)
            {
                int yIndexRAM = -0x10;
                int xIndexRAM = 0x140;
                word vramAddress = Calc_VRAM_Pos(position, yIndexRAM, xIndexRAM);

                //moveq	#-$10,d4
	        //moveq	#-$10,d5

                DrawTiles_TB(position, vramAddress, yIndexRAM, xIndexRAM, nametable, layoutIndex);
            }

            /*bclr	#4,(a2)
	    beq.s	locj_6D88
	    moveq	#-$10,d4
	    moveq	#$00,d5
	    bsr	Calc_VRAM_Pos_2
	    moveq	#-$10,d4
	    moveq	#0,d5
	    moveq	#$1F,d6
	    bsr	DrawTiles_LR_3
            locj_6D88:
            bclr	#5,(a2)
	    beq.s	locret_69F2
	    move.w	#$00E0,d4
	    moveq	#0,d5
	    bsr	Calc_VRAM_Pos_2
	    move.w	#$E0,d4
	    moveq	#0,d5
	    moveq	#$1F,d6
	    bsr	DrawTiles_LR_3
            */
        #endif
            
    }
}

void sub_69F4(word *linerenderField, long *position, word layoutIndex, int nametable)
{
    #if SONIC_REVISION == 0
    if (*linerenderField != 0)
    {
        byte uScreen = *linerenderField & 4;

        //clear bit 2
        *linerenderField = *linerenderField - uScreen;
       
        if (uScreen != 0 && LONGTOWORD(position[0]) > 16)
        {
            signed short numPixelsY = FFFFF7F0 - (LONGTOWORD(position[1]) & -0x10);
            int yIndexRAM = numPixelsY;
            int xIndexRAM = -0x10;
         
            word vramAddress = Calc_VRAM_Pos(position, yIndexRAM, xIndexRAM);
            
            //move.w	($FFFFF7F0).w,d6  
	    //move.w	4(a3),d1
	    //andi.w	#-$10,d1
	    //sub.w	d1,d6
            //...recalc of numPixelsY?
            if (numPixelsY > 0)
            {
                signed short numBlocks = (numPixelsY/16) - 14;
                if (numBlocks < 0) { numBlocks = -numBlocks; }
                
                DrawTiles_TB_2(position, vramAddress, yIndexRAM, xIndexRAM, numBlocks, nametable, layoutIndex);
            }
        }
        
        byte vScreen = *linerenderField & 8;

        //clear bit 3
        *linerenderField = *linerenderField - vScreen;
       
        if (vScreen != 0)
        {
            signed short numPixelsY = FFFFF7F0 - (LONGTOWORD(position[1]) & -0x10);
            int yIndexRAM = numPixelsY;
            int xIndexRAM = 0x140;
         
            word vramAddress = Calc_VRAM_Pos(position, yIndexRAM, xIndexRAM);
            
            //move.w	($FFFFF7F0).w,d6  
	    //move.w	4(a3),d1
	    //andi.w	#-$10,d1
	    //sub.w	d1,d6
            //...recalc of numPixelsY?
            if (numPixelsY > 0)
            {
                signed short numBlocks = (numPixelsY/16) - 14;
                if (numBlocks < 0) { numBlocks = -numBlocks; }
                
                DrawTiles_TB_2(position, vramAddress, yIndexRAM, xIndexRAM, numBlocks, nametable, layoutIndex);
            }
        }
    }
    #else
    /*
    			tst.b	(a2)
			beq	locj_6DF2
			cmpi.b	#id_SBZ,(v_zone).w
			beq	Draw_SBz
			bclr	#0,(a2)
			beq.s	locj_6DD2
			move.w	#$70,d4
			moveq	#-$10,d5
			bsr	Calc_VRAM_Pos
			move.w	#$70,d4
			moveq	#-$10,d5
			moveq	#2,d6
			bsr	DrawTiles_TB_2
	locj_6DD2:
			bclr	#1,(a2)
			beq.s	locj_6DF2
			move.w	#$70,d4
			move.w	#$140,d5
			bsr	Calc_VRAM_Pos
			move.w	#$70,d4
			move.w	#$140,d5
			moveq	#2,d6
			bsr	DrawTiles_TB_2
	locj_6DF2:
			rts
	locj_6DF4:
			dc.b $00,$00,$00,$00,$00,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$04
			dc.b $04,$04,$04,$04,$04,$04,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02
			dc.b $02,$00						
;===============================================================================
	Draw_SBz:
			moveq	#-$10,d4
			bclr	#0,(a2)
			bne.s	locj_6E28
			bclr	#1,(a2)
			beq.s	locj_6E72
			move.w	#$E0,d4
	locj_6E28:
			lea	(locj_6DF4+1),A0
			move.w	($FFFFF70C).w,d0
			add.w	d4,d0
			andi.w	#$1F0,d0
			lsr.w	#4,d0
			move.b	(a0,d0),d0
			lea	(locj_6FE4),a3
			move.w	(a3,d0),a3
			beq.s	locj_6E5E
			moveq	#-$10,d5
			movem.l	d4/d5,-(sp)
			bsr	Calc_VRAM_Pos
			movem.l	(sp)+,d4/d5
			bsr	DrawTiles_LR
			bra.s	locj_6E72
;===============================================================================
	locj_6E5E:
			moveq	#0,d5
			movem.l	d4/d5,-(sp)
			bsr	Calc_VRAM_Pos_2
			movem.l	(sp)+,d4/d5
			moveq	#$1F,d6
			bsr	DrawTiles_LR_3
	locj_6E72:
			tst.b	(a2)
			bne.s	locj_6E78
			rts
;===============================================================================			
	locj_6E78:
			moveq	#-$10,d4
			moveq	#-$10,d5
			move.b	(a2),d0
			andi.b	#$A8,d0
			beq.s	locj_6E8C
			lsr.b	#1,d0
			move.b	d0,(a2)
			move.w	#$140,d5
	locj_6E8C:
			lea	(locj_6DF4),a0
			move.w	($FFFFF70C).w,d0
			andi.w	#$1F0,d0
			lsr.w	#4,d0
			lea	(a0,d0),a0
			bra	locj_6FEC						
;===============================================================================



	locj_6EA4:
			tst.b	(a2)
			beq	locj_6EF0
			cmpi.b	#id_MZ,(v_zone).w
			beq	Draw_Mz
			bclr	#0,(a2)
			beq.s	locj_6ED0
			move.w	#$40,d4
			moveq	#-$10,d5
			bsr	Calc_VRAM_Pos
			move.w	#$40,d4
			moveq	#-$10,d5
			moveq	#2,d6
			bsr	DrawTiles_TB_2
	locj_6ED0:
			bclr	#1,(a2)
			beq.s	locj_6EF0
			move.w	#$40,d4
			move.w	#$140,d5
			bsr	Calc_VRAM_Pos
			move.w	#$40,d4
			move.w	#$140,d5
			moveq	#2,d6
			bsr	DrawTiles_TB_2
	locj_6EF0:
			rts
	locj_6EF2:
			dc.b $00,$00,$00,$00,$00,$00,$06,$06,$04,$04,$04,$04,$04,$04,$04,$04
			dc.b $04,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02
			dc.b $02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02
			dc.b $02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02
			dc.b $02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02
			dc.b $02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02
			dc.b $02,$00
;===============================================================================
	Draw_Mz:
			moveq	#-$10,d4
			bclr	#0,(a2)
			bne.s	locj_6F66
			bclr	#1,(a2)
			beq.s	locj_6FAE
			move.w	#$E0,d4
	locj_6F66:
			lea	(locj_6EF2+1),a0
			move.w	($FFFFF70C).w,d0
			subi.w	#$200,d0
			add.w	d4,d0
			andi.w	#$7F0,d0
			lsr.w	#4,d0
			move.b	(a0,d0),d0
			move.w	locj_6FE4(pc,d0),a3
			beq.s	locj_6F9A
			moveq	#-$10,d5
			movem.l	d4/d5,-(sp)
			bsr	Calc_VRAM_Pos
			movem.l	(sp)+,d4/d5
			bsr	DrawTiles_LR
			bra.s	locj_6FAE
;===============================================================================
	locj_6F9A:
			moveq	#0,d5
			movem.l	d4/d5,-(sp)
			bsr	Calc_VRAM_Pos_2
			movem.l	(sp)+,d4/d5
			moveq	#$1F,d6
			bsr	DrawTiles_LR_3
	locj_6FAE:
			tst.b	(a2)
			bne.s	locj_6FB4
			rts
;===============================================================================			
	locj_6FB4:
			moveq	#-$10,d4
			moveq	#-$10,d5
			move.b	(a2),d0
			andi.b	#$A8,d0
			beq.s	locj_6FC8
			lsr.b	#1,d0
			move.b	d0,(a2)
			move.w	#$140,d5
	locj_6FC8:
			lea	(locj_6EF2),a0
			move.w	($FFFFF70C).w,d0
			subi.w	#$200,d0
			andi.w	#$7F0,d0
			lsr.w	#4,d0
			lea	(a0,d0),a0
			bra	locj_6FEC
;===============================================================================			
	locj_6FE4:
			dc.b $FF,$18,$FF,$18,$FF,$20,$FF,$28
	locj_6FEC:
			moveq	#$F,d6
			move.l	#$800000,d7
	locj_6FF4:			
			moveq	#0,d0
			move.b	(a0)+,d0
			btst	d0,(a2)
			beq.s	locj_701C
			move.w	locj_6FE4(pc,d0),a3
			movem.l	d4/d5/a0,-(sp)
			movem.l	d4/d5,-(sp)
			bsr	DrawBlocks
			movem.l	(sp)+,d4/d5
			bsr	Calc_VRAM_Pos
			bsr	DrawTiles
			movem.l	(sp)+,d4/d5/a0
	locj_701C:
			addi.w	#$10,d4
			dbra	d6,locj_6FF4
			clr.b	(a2)
			rts		
     */
    #endif	
}

/* ADDITIONAL UNUSED DRAWRING SUBROUTINES
		tst.b	(a2)
		beq.s	locret_6AD6
		bclr	#2,(a2)
		beq.s	loc_6AAC
		move.w	#$D0,d4
		move.w	4(a3),d1
		andi.w	#-$10,d1
		sub.w	d1,d4
		move.w	d4,-(sp)
		moveq	#-$10,d5
		bsr.w	sub_6C3C
		move.w	(sp)+,d4
		moveq	#-$10,d5
		moveq	#2,d6
		bsr.w	DrawTiles_TB_2

loc_6AAC:
		bclr	#3,(a2)
		beq.s	locret_6AD6
		move.w	#$D0,d4
		move.w	4(a3),d1
		andi.w	#-$10,d1
		sub.w	d1,d4
		move.w	d4,-(sp)
		move.w	#$140,d5
		bsr.w	sub_6C3C
		move.w	(sp)+,d4
		move.w	#$140,d5
		moveq	#2,d6
		bsr.w	DrawTiles_TB_2

locret_6AD6:
		rts	

*/

            

            
void LoadTilesFromStart()
{    
    DrawChunks(&v_screenposx, 0x4000, 0);
	
    //#define SONIC_REVISION 0
    //#if SONIC_REVISION==0
    DrawChunks(&FFFFF708, 0x6000, 0x40); /*a3=$FFFFF708*, bglayout);*/
    //#else
    //different bg drawing functions
    //#endif
    
    //additional work for zones here
}

void DrawChunks(long *screenPos, int num, word layoutIndex)
{
    
    //The tile display for each plane is controlled by that plane's name table.
    //The size of the name table can vary, but in Mega Drive Sonic games the size of the planes is usually 64x32 cells, or 512x256 pixels. 
    //The format of the name table is simple - one word per 8x8 tile, 
    //that word having the format PCCV HAAA AAAA AAAA,
    // - where P is the high priority flag, 
    // - CC is the palette line to use,
    // - V and H are the vertical and horizontal flip flags, respectively,
    // - AAA AAAA AAAA is the tile index of the 8x8 tile (i.e. VRAM location / $20). 
    //Since the size of the name tables generally exceeds the visible display area, horizontal and vertical scrolling techniques are used 
    //to select the part of the name table to be displayed in the visible area.

    //Both the foreground and background nametables (2) in RAM are sized 64x32 (grid of 8x8 tiles)
    //this allows for a virtual resolution of 512x256 pixels
    //consider the size limitations of the genesis (320x224), 
    // - 24 tiles (192 pixels) horizontally offscreen (physically to the right, virtually wraps back to the left)
    // - 4 tiles   (32 pixels)  vertically offscreen  (physically below, virtually wraps up to the top)
    //..
    //a vertical position of -16  or -0x10  then is actually 0xF0 (240)
    // which is ( (240-224) / 8 ) = 2 8x8 tiles (1 16x16) -below- the offscreen area
    // and of course at this position there is room for only 2 more 8x8 tiles (1 16x16), before wrapping back up to the top
    // so -virtually- we can refer to this position of -16 pixels as being above screen, as it makes more sense visually

    signed int yIndexRAM=-16;  //offset to add to y when calculating
    int xIndexRAM=0;           //offset to add to x when calculating
    int numLines=16;           //number of lines (from top to bottom) to draw  
    int numBlocks=31;          //length of lines, 31 times left to right to cover half of foreground ram x-wise
    
    for (; numLines>=0; numLines--)
    {
       
        //play area is basically divided by grouping of 512 x 256 pix chunks

        //-|-|-|-|-------|------------|-----------|
        //   512pix      512pix       512pix

        //on start, screenx is rounded to the nearest 512 pix chunk, [in terms of 64 8x8 tiles]
        //
        //where in fg ram the chunk (sum of lines) will be placed initially is HORIZONTALLY offset by the same offset 
        //   ..in units of 8x8 tiles in the nearest 512 pix chunk
        //the chunk will begin horizontally at this offset and wrap from right to left all the way back 
        //this allows for the horizontal scroll value to ultimately shift this offset BACK (because the scroll values also wrap)
        //calc vram pos returns this offset index into fgram based on the location:
        //    [(screenx % 512)+xIndexRAM, (screeny % 256)+yIndexRAM]
        
        //(for each line (16) in the chunk, yIndexRAM being the iterator) 
        long d0=Calc_VRAM_Pos(screenPos, yIndexRAM, xIndexRAM);
     
        //keep in mind that the above has NOTHING to do with using screenx & screeny to READ the proper 256/16 chunks/blocks
        // (this is what is instead eventually accomplished with drawblocks)
        //it only accounts for the offset created by horizontal scrolling so it knows WHERE to start LOADING the chunks/(sum of block lines)

        //=========================================================
        //starting at the calculated position in ram, 8x8 tiles can then be loaded from left to right
        //(DrawTiles_LR forces a default value of 21 for number of blocks left to right for the actual drawing subroutine DrawTiles_LR_2)
        //DrawTiles_LR_2 needs to know:
        //   number of blocks in line to place left to right  
        //   16x16 x iterator(xIndexRAM/v2) initial position: (0) shifts the entire line left or right    
        //   line y position(yIndexRAM)
        //   which of the 2 nametables (fg or bg) to place the line

        //   which layout (fg or bg) to grab tile/block data
        //   screenx & screeny to know which 256 chunk (and starting at the nearest 16x16 block) to grab (used with iterators)
        //   (calculated position in ram to account for screen shift)          
        
        //(for each line (16) in the chunk, yIndexRAM/line y position being the iterator)
        DrawTiles_LR_2(screenPos, d0, yIndexRAM, xIndexRAM, numBlocks, num, layoutIndex); 
        yIndexRAM=yIndexRAM+16; 
    }
    
}

word Calc_VRAM_Pos(long *position, int offsety, int offsetx)
{
    int ypos = LONGTOWORD(position[1]) + (offsety);
    int xpos = LONGTOWORD(position[0]) + (offsetx);

    word ypos16 = ypos & 0xF0;
    word xpos16 = xpos & 0x1F0;

    word byteaddress = (xpos16/4) + (ypos16*16);

    //return 0x30000+address;
    return byteaddress/2;
}

/*long calcVramPos(int screenx, int screeny, int val1, int val2)//accounts for offset into 256 tile to grab 16x16 based on screen position
{  
    val1=val1+screeny;
    val2=val2+screenx;
    val1&=0xF0; //round to nearest multiple of 16, screen.y in terms of 16x16s < 255
    val2&=0x1F0;//round to nearest multiple of 16, screen.x in terms of 16x16s < 512
	
    //val1=val1*16; //bytes per line
    //val2=val2/4;  //bytes per x value
    val1=(val1/16)*128;
    val2=(val2/16);
    
    //return 0x30000+val1+val2;
    //^genesis calculations, we are concerned with returning an index here
    
    return val1+val2;
}*/

inline void DrawTiles_LR(long *screenPos, int tileIndex, long v1, long v2, int num, word layoutIndex)
{
    long v3 = 21;
    DrawTiles_LR_2(screenPos, tileIndex, v1, v2, v3, num, layoutIndex);
}

void DrawTiles_LR_2(long *screenPos, int tileIndex, long v1, long v2, long v3, int num, word layoutIndex)
{
    long d7 = 0x800000;      //value to add for vdp write
    long d1 = tileIndex;     //drawblocks needs to know the offset where to start loading blocks

    //for each 16x16 block in this line(v3)...
    for (int times=0; times <= v3; times++)
    {

        //v1=value used to iterate the drawing position y-wise, will stay constant through this loop for we are drawing a line from l to r 
        //v2=value used to iterate the drawing position x-wise, will accumulate for each 16x16 block (through this loop)

        //drawblocks calulates position of current 16x16 in current 256x256 mapping at screen location + iterators
        //  (screenx + v2), (screeny + v1)
        //....layoutIndex refers to either fg or bg layout to use for grabbing 256's/16's
        word *a1=DrawBlocks(screenPos, v1, v2, layoutIndex);
    	
        //now that the proper 16x16 block has been located for this position, its 4 8x8 tiles can be loaded into ram
        //DrawTiles: vram position, fg or bg nametable, which block's tiles
        DrawTiles(d1, num, a1);
     
        //increment position in vram, 2 8x8 tiles over for the width of a block (2x2) 
    	d1 = d1 + 2;       

        //wrap chunks that will eventually exceed the nametable width when drawing further to the right of their initial offset position  
    	d1 = d1 & 0xFFBF;   //wrap
    	
        //next 16x16 block in the line..
    	v2=v2+16;
    }
	
}

inline void DrawTiles_TB(long *screenPos, int tileIndex, long v1, long v2, int num, word layoutIndex)
{
    long v3 = 15;
    DrawTiles_TB_2(screenPos, tileIndex, v1, v2, v3, num, layoutIndex);
}

void DrawTiles_TB_2(long *screenPos, int tileIndex, long v1, long v2, long v3, int num, word layoutIndex)
{
    long d7 = 0x800000;      //value to add for vdp write
    long d1 = tileIndex;     //drawblocks needs to know the offset where to start loading blocks

    //for each 16x16 block in this line(v3)...
    for (int times=0; times <= v3; times++)
    {

        //v1=value used to iterate the drawing position y-wise, will accumulate for each 16x16 block (through this loop)
        //v2=value used to iterate the drawing position x-wise, will stay constant through this loop for we are drawing a line from t to b

        //drawblocks calulates position of current 16x16 in current 256x256 mapping at screen location + iterators
        //  (screenx + v2), (screeny + v1)
        //....layoutIndex refers to either fg or bg layout to use for grabbing 256's/16's
        word *a1=DrawBlocks(screenPos, v1, v2, layoutIndex);
    	
        //now that the proper 16x16 block has been located for this position, its 4 8x8 tiles can be loaded into ram
        //DrawTiles: vram position, fg or bg nametable, which block's tiles
        DrawTiles(d1, num, a1);
     
        //increment position in vram, 2 8x8 tiles below for the height of a block (2x2) 
    	d1 = d1 + 128;       

        //wrap chunks that will eventually exceed the nametable height when drawing further below their initial offset position  
    	d1 = d1 & 0x7FF;   //wrap
    	
        //next 16x16 block in the line..
    	v1=v1+16;
    }
	
}

void DrawTiles(int tile, int num, word *v_16x16)
{
    #define DrawTileFG fgTile
    #define DrawTileBG bgTile

    //tile is the index in which to place the tiles drawn for this 16x16
    //tile = (word)tile | (word)(num-0x4000);   //d2 is passed in DrawChunks, this is what is added to vram for placement of tiles in either fg (0x4000) or bg (0x6000)
	
    //tile = tile * 65536;  //swap function in rom
	
    //btst	#4,(a0)
    //	bne.s	DrawFlipY
    //	btst	#3,(a0)
    //	bne.s	DrawFlipX

    //int TLENGTH=64;
    //int THEIGHT=64;
	
    word cur16val;

    if (flipx==1 && flipy!=1) 
    { 
        cur16val=SWAPWORD(v_16x16[0]);
        cur16val=(cur16val ^ (1<<11));
        //cur16val=(cur16val ^ (flipy<<12));

        if (num==0x4000)
            DrawTileFG(tile+1, cur16val); //vram offset divided by 0x20
        else if (num==0x6000)
            DrawTileBG(tile+1, cur16val);

           
        cur16val=SWAPWORD(v_16x16[1]);
        cur16val=(cur16val ^ (1<<11));
        //cur16val=(cur16val ^ (flipy<<12));
        
        if (num==0x4000)
           DrawTileFG(tile, cur16val); //vram offset divided by 0x20
        else if (num==0x6000)
           DrawTileBG(tile, cur16val);

        
        cur16val=SWAPWORD(v_16x16[2]);
        cur16val=(cur16val ^ (1<<11));
        //cur16val=(cur16val ^ (flipy<<12));
        
        if (num==0x4000)
            DrawTileFG(tile+65, cur16val); //vram offset divided by 0x20
        else if (num==0x6000)
            DrawTileBG(tile+65, cur16val);

        
        cur16val=SWAPWORD(v_16x16[3]);
        cur16val=(cur16val ^ (1<<11));
        //cur16val=(cur16val ^ (flipy<<12));
      
        if (num==0x4000)
            DrawTileFG(tile+64, cur16val); //vram offset divided by 0x20
        else if (num==0x6000)
            DrawTileBG(tile+64, cur16val);

    }
    else if (flipy==1&&flipx!=1)
    {
        cur16val=SWAPWORD(v_16x16[0]);
        //cur16val=(cur16val ^ (flipx<<11));
        cur16val=(cur16val ^ (1<<12));
    
        if (num==0x4000)
            DrawTileFG(tile+64, cur16val); //vram offset divided by 0x20
        else if (num==0x6000)
            DrawTileBG(tile+64, cur16val);

           
        cur16val=SWAPWORD(v_16x16[1]);
        //cur16val=(cur16val ^ (flipx<<11));
        cur16val=(cur16val ^ (1<<12));
        
        if (num==0x4000)
            DrawTileFG(tile+65, cur16val); //vram offset divided by 0x20
        else if (num==0x6000)
            DrawTileBG(tile+65, cur16val);

              
        cur16val=SWAPWORD(v_16x16[2]);
        //cur16val=(cur16val ^ (flipx<<11));
        cur16val=(cur16val ^ (1<<12));
        
        if (num==0x4000)
            DrawTileFG(tile, cur16val); //vram offset divided by 0x20
        else if (num==0x6000)
            DrawTileBG(tile, cur16val);

        
        cur16val=SWAPWORD(v_16x16[3]);
        //cur16val=(cur16val ^ (flipx<<11));
        cur16val=(cur16val ^ (1<<12));
      
        if (num==0x4000)
            DrawTileFG(tile+1, cur16val); //vram offset divided by 0x20
        else if (num==0x6000)
            DrawTileBG(tile+1, cur16val);

    }
    else if (flipx ==1 && flipy ==1)
    {         
        cur16val=SWAPWORD(v_16x16[0]);
        cur16val=(cur16val ^ (1<<11));
        cur16val=(cur16val ^ (1<<12));
        
        if (num==0x4000)
            DrawTileFG(tile+65, cur16val); //vram offset divided by 0x20
        else if (num==0x6000)
            DrawTileBG(tile+65, cur16val);
               
        
        cur16val=SWAPWORD(v_16x16[1]);
        cur16val=(cur16val ^ (1<<11));
        cur16val=(cur16val ^ (1<<12));
        
        if (num==0x4000)
            DrawTileFG(tile+64, cur16val); //vram offset divided by 0x20
        else if (num==0x6000)
            DrawTileBG(tile+64, cur16val);
            
            
        cur16val=SWAPWORD(v_16x16[2]);
        cur16val=(cur16val ^ (1<<11));
        cur16val=(cur16val ^ (1<<12));
            
        if (num==0x4000)
            DrawTileFG(tile+1, cur16val); //vram offset divided by 0x20
        else if (num==0x6000)
            DrawTileBG(tile+1, cur16val);
            
        
        cur16val=SWAPWORD(v_16x16[3]);
        cur16val=(cur16val ^ (1<<11));
        cur16val=(cur16val ^ (1<<12));
          
        if (num==0x4000)
            DrawTileFG(tile, cur16val); //vram offset divided by 0x20
        else if (num==0x6000)
            DrawTileBG(tile, cur16val);
    }
      
    if (flipx!=1 && flipy!=1)
    {   
        cur16val=SWAPWORD(v_16x16[0]);
           
        if (num==0x4000)
            DrawTileFG(tile, cur16val); //vram offset divided by 0x20
        else if (num==0x6000)
            DrawTileBG(tile, cur16val);
               
        
        cur16val=SWAPWORD(v_16x16[1]);
            
        if (num==0x4000)
            DrawTileFG(tile+1, cur16val); //vram offset divided by 0x20
        else if (num==0x6000)
            DrawTileBG(tile+1, cur16val);
            
        
        cur16val=SWAPWORD(v_16x16[2]);
            
        if (num==0x4000)
            DrawTileFG(tile+64, cur16val); //vram offset divided by 0x20
        else if (num==0x6000)
            DrawTileBG(tile+64, cur16val);
            
        
        cur16val=SWAPWORD(v_16x16[3]);
          
        if (num==0x4000)
            DrawTileFG(tile+65, cur16val); //vram offset divided by 0x20
        else if (num==0x6000)
            DrawTileBG(tile+65, cur16val);
    }    
           
}           



word *DrawBlocks(long *screenPos, long v1, long v2, word layoutIndex)     //screen pos offset by v1 (x) and v2 (y) used to locate position of 16x16 mapping referred to by upper left most screen pos
{    
    v1=v1+LONGTOWORD(screenPos[1]);     //screeny
    v2=v2+LONGTOWORD(screenPos[0]);     //screenx
    
    //word *a1=(word*)currentZone.v_16x16;  
      	  
    //if (v1<0 || v2<0) { /*printf("2) v1 or v2 is less than 0 so end...\n");*/ return (word*)currentZone.v_16x16; }
    if (v1<0 || v2<0) { /*printf("2) v1 or v2 is less than 0 so end...\n");*/ return (word*)v_16x16; }

    unsigned short d3 = (v1/2) & 0x380; //(scaled y value to nearest 256)/2
    v2=v2/8;                      //(scaled x value per tile);
    	
    word vram=v2;                  //vram=current tile at screen x
    vram=vram/32;                 //(vram=(current tile at screen x)/32=current 256x256 at screen location(index)
	   
    //yoff=yoff*(currentZone.width[layoutIndex/0x40]);  //?
       
    vram=vram & 0x7F;             //(no bigger than 128)
    vram=(vram+(d3));                 //compensate for the y val too
     
    //word temp256=currentZone.v_lvllayout[vram+((layoutIndex)*8)];
    word temp256 = v_lvllayout[vram+layoutIndex];

    word cur256=temp256;       //cur256=current level 256x256 at screen location calculated in vram
	
    #ifdef debug_tiles
    if (old256!=temp256){/*printf("Drawing block at %i in v_lvllayout: %i \n", vram, cur256)*/}
    #endif
    
    old256=temp256;
    if (temp256 == 0) { /*printf("6) temp256==0, no 256 here...\n"); return (word*)currentZone.v_16x16; */}
    
    cur256=cur256-1; 
    cur256=cur256 & 0x007F;//this index value is never greater than 127
    //cur256=(cur256 << 8);        //this is9 in rom, or a rotr 7
    cur256=(cur256<<9);//+(cur256>>7);
    
    #ifdef debug_tiles
    //printf("cur256: %i\n", cur256);
    #endif
    
    //v1=used as offset index value into different mappings arrays based on screen y  (currently per pixel, has yet to be scaled)
    //v2=used as offset index value into different mappings arrays based on screen x  (currently per tile)
    //v1=v1/16;

    v1=v1*2;      //extra bit to left, current 16x16 at y location translates to twice thesize for wordsize of 16x16

	
   v1=v1&0x1E0;  //0000000111100000       v1 scaled and now yields (tile offset [0,Y]): (0<=Y<16) where Y is current 16x16 tile offset into 256 based on screen y
   v2=v2&0x1E;   //0000000000011110       v2 scaled and now yields (tile offset [X,0]): (0<=X<16) where X is current 16x16 tile offset into 256 based on screen x    

	
   unsigned short cur16index;
		
   cur16index=cur256+v1+v2;  //256TILEYYYYXXXX0 //two offsets are added along with the index value RELATIVE ADDRESS 0F CURRENT 16X16 MAPPING IN CORRESPONDING 256
   //cur16index=cur16index/2;      //compensate for the word
	
	//long a0=d3;                   //RELATIVE ADDRESS 0F CURRENT 16X16 MAPPING IN CORRESPONDING 256
	//d3=*(a0);                      //we can grab value like this for 256x256 mappings reside at $0000 in RAM, therefore to calculate the relative address NOTHING is added
	//d3=(d3);
                        
   //this is pc side
   unsigned short cur16;

    //unsigned short temp=((currentZone.v_256x256[cur16index]))+(currentZone.v_256x256[cur16index-1]<<8); 
    unsigned short temp=((v_256x256[cur16index])<<8)+(v_256x256[cur16index+1]);
    cur16=temp & 0x3FF;
    
    flipx=((temp & 0x800)>>11);      //these are calculated elsewhere in therom
    flipy=((temp & 0x1000)>>12);

    //cur16=cur16&0xFFFF;                     //
    //cur16=cur16&0x03FF;                     //d3=index in 16x16s referred to
    cur16=cur16*8;                         //size of 1 16x16mapping
	
    //a1=a1+cur16;                           //16x16 position added to relative offset
    //word *a1=(word*)&currentZone.v_16x16[cur16];
    word *a1=(word*)&v_16x16[cur16];

    return a1;

}

byte ArtUnc_MenuText[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x00,0x06,0x60,0x06,
0x60,0x66,0x60,0x66,0x60,0x66,0x66,0x06,0x60,0x66,0x00,0x66,0x00,0x06,0x66,
0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x66,0x00,0x00,
0x60,0x66,0x00,0x00,0x00,0x66,0x00,0x00,0x06,0x60,0x00,0x00,0x06,0x60,0x00,
0x06,0x66,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x60,
0x00,0x06,0x00,0x66,0x00,0x00,0x00,0x66,0x00,0x00,0x06,0x60,0x00,0x00,0x66,
0x00,0x00,0x06,0x66,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,
0x66,0x66,0x00,0x00,0x00,0x66,0x00,0x00,0x06,0x60,0x00,0x00,0x00,0x66,0x00,
0x06,0x00,0x66,0x00,0x06,0x66,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x06,0x66,0x00,0x00,0x60,0x66,0x00,0x06,0x00,0x60,0x00,0x66,0x66,
0x66,0x60,0x00,0x06,0x60,0x00,0x00,0x66,0x60,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x66,0x66,0x00,0x00,0x60,0x00,0x00,0x00,0x66,0x66,0x00,
0x00,0x00,0x06,0x60,0x06,0x00,0x66,0x60,0x00,0x66,0x66,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x66,0x00,0x00,0x66,0x00,0x00,0x06,0x66,
0x60,0x00,0x66,0x00,0x66,0x00,0x66,0x00,0x66,0x00,0x66,0x66,0x60,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x66,0x66,0x00,0x06,0x00,0x66,0x00,
0x00,0x06,0x60,0x00,0x00,0x66,0x00,0x00,0x06,0x60,0x00,0x00,0x66,0x60,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x00,0x06,0x60,
0x06,0x60,0x00,0x66,0x66,0x00,0x06,0x66,0x60,0x00,0x66,0x00,0x66,0x00,0x06,
0x66,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x00,
0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x00,0x66,0x66,0x00,0x00,0x00,0x66,
0x00,0x06,0x66,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x66,
0x66,0x00,0x06,0x06,0x00,0x00,0x00,0x66,0x60,0x00,0x00,0x06,0x06,0x00,0x06,
0x66,0x60,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x66,0x66,0x60,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x66,0x66,0x60,0x00,0x00,0x00,0x00,0x06,
0x66,0x66,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x60,0x00,0x00,0x00,0x66,0x00,0x06,0x66,0x66,0x60,0x06,0x66,0x66,
0x60,0x00,0x00,0x66,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x66,0x00,0x06,0x66,0x66,0x60,0x06,
0x66,0x66,0x60,0x00,0x00,0x66,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x60,0x06,0x60,0x06,0x60,0x06,
0x60,0x00,0x60,0x66,0x00,0x00,0x66,0x60,0x00,0x06,0x66,0x00,0x00,0x66,0x60,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x66,0x66,0x60,0x00,
0x00,0x66,0x00,0x00,0x06,0x60,0x00,0x00,0x66,0x00,0x00,0x06,0x60,0x00,0x00,
0x66,0x66,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,
0x60,0x00,0x06,0x06,0x60,0x00,0x60,0x06,0x60,0x00,0x66,0x66,0x60,0x06,0x60,
0x06,0x60,0x66,0x00,0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x66,0x66,0x00,0x00,0x60,0x06,0x60,0x06,0x66,0x66,0x00,0x06,0x66,0x60,0x00,
0x66,0x00,0x66,0x00,0x66,0x66,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x66,0x66,0x00,0x06,0x60,0x06,0x60,0x06,0x60,0x00,0x00,0x66,0x00,
0x00,0x00,0x66,0x00,0x66,0x00,0x66,0x66,0x60,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x66,0x66,0x00,0x00,0x66,0x06,0x60,0x06,0x60,0x06,0x60,
0x06,0x60,0x06,0x60,0x66,0x00,0x66,0x00,0x66,0x66,0x60,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x60,0x00,0x66,0x00,0x00,0x06,0x60,
0x00,0x00,0x06,0x66,0x60,0x00,0x66,0x00,0x00,0x00,0x66,0x66,0x66,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x60,0x06,0x66,0x00,0x00,
0x06,0x60,0x00,0x00,0x06,0x66,0x66,0x00,0x66,0x60,0x00,0x00,0x66,0x60,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x00,0x06,0x66,
0x00,0x60,0x06,0x60,0x00,0x00,0x66,0x00,0x66,0x60,0x66,0x00,0x66,0x00,0x66,
0x66,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x00,0x60,
0x00,0x66,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x66,0x66,0x00,0x66,0x00,0x66,
0x00,0x66,0x00,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,
0x60,0x00,0x00,0x06,0x60,0x00,0x00,0x66,0x00,0x00,0x00,0x66,0x00,0x00,0x06,
0x60,0x00,0x00,0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x06,0x60,0x00,0x00,0x06,0x60,0x06,0x00,0x66,0x00,0x66,0x00,0x66,
0x00,0x66,0x66,0x60,0x00,0x06,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x66,0x00,0x60,0x00,0x66,0x06,0x60,0x06,0x60,0x66,0x00,0x06,
0x66,0x60,0x00,0x66,0x00,0x66,0x00,0x66,0x00,0x06,0x60,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x06,0x60,0x00,0x00,0x66,0x00,0x00,0x06,0x60,0x00,
0x00,0x06,0x60,0x00,0x00,0x66,0x00,0x00,0x00,0x66,0x66,0x66,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x00,0x60,0x00,0x66,0x06,0x60,0x00,
0x66,0x66,0x60,0x06,0x06,0x06,0x60,0x06,0x00,0x06,0x60,0x66,0x00,0x06,0x60,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x00,0x60,0x00,0x66,0x00,
0x60,0x00,0x66,0x60,0x60,0x06,0x06,0x66,0x00,0x06,0x00,0x66,0x00,0x66,0x00,
0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x00,0x06,
0x60,0x06,0x60,0x66,0x60,0x66,0x60,0x66,0x60,0x66,0x60,0x66,0x00,0x66,0x00,
0x06,0x66,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x66,
0x00,0x00,0x66,0x00,0x60,0x06,0x60,0x06,0x60,0x06,0x66,0x66,0x00,0x66,0x60,
0x00,0x00,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x66,0x66,0x00,0x06,0x60,0x06,0x60,0x66,0x00,0x06,0x60,0x66,0x66,0x66,0x60,
0x66,0x00,0x66,0x00,0x66,0x66,0x66,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x66,0x66,0x00,0x00,0x66,0x00,0x60,0x06,0x60,0x06,0x60,0x06,0x66,
0x66,0x00,0x66,0x00,0x66,0x00,0x66,0x00,0x66,0x60,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x66,0x66,0x60,0x06,0x60,0x06,0x60,0x06,0x66,0x00,0x00,
0x00,0x66,0x66,0x00,0x66,0x00,0x66,0x60,0x66,0x66,0x66,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x06,0x66,0x66,0x60,0x00,0x06,0x60,0x00,0x00,0x06,
0x60,0x00,0x00,0x66,0x00,0x00,0x00,0x66,0x00,0x00,0x00,0x66,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x00,0x60,0x00,0x66,0x00,0x60,
0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x00,0x66,0x66,0x66,0x00,0x66,0x66,0x60,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x60,0x00,0x60,0x06,0x60,
0x00,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x66,0x00,0x06,0x66,0x60,0x00,0x66,
0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x00,0x00,0x60,
0x66,0x00,0x00,0x60,0x66,0x06,0x06,0x60,0x66,0x66,0x66,0x00,0x66,0x00,0x66,
0x00,0x66,0x00,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x60,
0x00,0x60,0x06,0x66,0x06,0x00,0x00,0x66,0x60,0x00,0x00,0x06,0x60,0x00,0x00,
0x66,0x66,0x00,0x66,0x00,0x66,0x60
};


//ShowErrorMessage:
void DrawText(char* text, int len, int x, int y)
{
     
        char *gentext=PCtoSonicText(text,len);
        
		//lea	(vdp_data_port).l,a6
		//locVRAM	$F800
	    word *vRambuf=getvRam();
	        
    	//lea	(Art_Text).l,a0
		for (int d1=0x27F, index=0; d1>0; d1--, index++)
        {
            //move.w	#$27F,d1
            //@loadgfx:
            //move.w	(a0)+,(a6)	        
            vRambuf[index+(0xF800/2)]=((ArtUnc_MenuText[index*2]<<8)&0xFF00)+((ArtUnc_MenuText[(index*2)+1])&0x00FF);
        }//dbf	d1,@loadgfx

		//WHERE DRAWTEXT WILL DIFFER FROM THE ORIGINAL ERROR TEXT ROUTINE DIFFERS HERE...
        //moveq	#0,d0		; clear	d0
		//move.b	(v_errortype).w,d0 ; load error code
		//move.w	ErrorText(pc,d0.w),d0
		//lea	ErrorText(pc,d0.w),a0
		//--------------
		//WE WANT TO PLACE THE TEXT IN VRAM
        
        //***locVRAM	(vram_fg+$604)
		//word *fgRambuf=getfgRam();
		
        //moveq	#$12,d1		; number of characters (minus 1)  (D1 HERE IS LENGTH, len CAN BE THE LENGTH AS AN ADDITIONAL ARGUMENT..)

		for (int count=0;len>0; len--,count++)
		{
	    //@showchars:
		//moveq	#0,d0
		//move.b	(a0)+,d0     A0 now refers to the text, source will be the string in our case
		//addi.w	#$790,d0
		//***move.w	d0,(a6)
            //printf("gentext[count]=%i\n", gentext[count]);
            //fgRambuf[(y*64)+x+count]=gentext[count]+0x2000+0x790;//(0x790;   //
            word tileval=(((byte)(gentext[count]))+0x7C0)^0x2000;
            //tileval=((tileval&0x00FF)<<8)+((tileval&0xFF00)>>8);
            DrawTileFG((y*64)+x+count,tileval);
        }//dbf	d1,@showchars	; repeat for number of characters
		//rts
}	

void DrawText_NoScroll(char* text, int len, int x, int y)
{
     
        char *gentext=PCtoSonicText(text,len);
        
		//lea	(vdp_data_port).l,a6
		//locVRAM	$F800
	    word *vRambuf=getvRam();
	        
    	//lea	(Art_Text).l,a0
		for (int d1=0x27F, index=0; d1>0; d1--, index++)
        {
            //move.w	#$27F,d1
            //@loadgfx:
            //move.w	(a0)+,(a6)	        
            vRambuf[index+(0xF800/2)]=((ArtUnc_MenuText[index*2]<<8)&0xFF00)+((ArtUnc_MenuText[(index*2)+1])&0x00FF);
        }//dbf	d1,@loadgfx

		//WHERE DRAWTEXT WILL DIFFER FROM THE ORIGINAL ERROR TEXT ROUTINE DIFFERS HERE...
        //moveq	#0,d0		; clear	d0
		//move.b	(v_errortype).w,d0 ; load error code
		//move.w	ErrorText(pc,d0.w),d0
		//lea	ErrorText(pc,d0.w),a0
		//--------------
		//WE WANT TO PLACE THE TEXT IN VRAM
        
        //***locVRAM	(vram_fg+$604)
		//word *fgRambuf=getfgRam();
		
        //moveq	#$12,d1		; number of characters (minus 1)  (D1 HERE IS LENGTH, len CAN BE THE LENGTH AS AN ADDITIONAL ARGUMENT..)

		for (int count=0;len>0; len--,count++)
		{
	    //@showchars:
		//moveq	#0,d0
		//move.b	(a0)+,d0     A0 now refers to the text, source will be the string in our case
		//addi.w	#$790,d0
		//***move.w	d0,(a6)
            //printf("gentext[count]=%i\n", gentext[count]);
            //fgRambuf[(y*64)+x+count]=gentext[count]+0x2000+0x790;//(0x790;   //
            word tileval=(((byte)(gentext[count]))+0x7C0)^0x2000;
            //tileval=((tileval&0x00FF)<<8)+((tileval&0xFF00)>>8);
            textTile((y*64)+x+count,tileval);
        }//dbf	d1,@showchars	; repeat for number of characters
		//rts
}

void DrawText_NoScrollExt(char* text, int len, int x, int y, word *ram)
{
     
        char *gentext=PCtoSonicText(text,len);
        
		//lea	(vdp_data_port).l,a6
		//locVRAM	$F800
	    word *vRambuf=getvRam();
	        
    	//lea	(Art_Text).l,a0
		for (int d1=0x27F, index=0; d1>0; d1--, index++)
        {
            //move.w	#$27F,d1
            //@loadgfx:
            //move.w	(a0)+,(a6)	        
            vRambuf[index+(0xF800/2)]=((ArtUnc_MenuText[index*2]<<8)&0xFF00)+((ArtUnc_MenuText[(index*2)+1])&0x00FF);
        }//dbf	d1,@loadgfx

		//WHERE DRAWTEXT WILL DIFFER FROM THE ORIGINAL ERROR TEXT ROUTINE DIFFERS HERE...
        //moveq	#0,d0		; clear	d0
		//move.b	(v_errortype).w,d0 ; load error code
		//move.w	ErrorText(pc,d0.w),d0
		//lea	ErrorText(pc,d0.w),a0
		//--------------
		//WE WANT TO PLACE THE TEXT IN VRAM
        
        //***locVRAM	(vram_fg+$604)
		//word *fgRambuf=getfgRam();
		
        //moveq	#$12,d1		; number of characters (minus 1)  (D1 HERE IS LENGTH, len CAN BE THE LENGTH AS AN ADDITIONAL ARGUMENT..)

		for (int count=0;len>0; len--,count++)
		{
	    //@showchars:
		//moveq	#0,d0
		//move.b	(a0)+,d0     A0 now refers to the text, source will be the string in our case
		//addi.w	#$790,d0
		//***move.w	d0,(a6)
            //printf("gentext[count]=%i\n", gentext[count]);
            //fgRambuf[(y*64)+x+count]=gentext[count]+0x2000+0x790;//(0x790;   //
            word tileval=(((byte)(gentext[count]))+0x7C0)^0x2000;
            //tileval=((tileval&0x00FF)<<8)+((tileval&0xFF00)>>8);
            textTileExt((y*64)+x+count,tileval,ram);
        }//dbf	d1,@showchars	; repeat for number of characters
		//rts
}

char *PCtoSonicText(char *pcText, int len)
{
     
     for (int lp=0; lp<len; lp++)
     {
         byte charVal=pcText[lp];  //art starts at 48th ASCII index, '0'    
         byte newVal;
         if (charVal==32) { newVal=42; }
         else if (charVal==36) { newVal=10; }  // '$' dollar sign is 10th index
         else if (charVal==45) { newVal=11; }  // '-' minus sign is 11th index
         else if (charVal>=48 && charVal <= 57) 
                 newVal=charVal-48;    
         else if (charVal==61) { newVal=12; }  // '=' equals is 12th index
         //todo: implement two arrow type characters
         else if ((charVal>=65) && (charVal<=88)) //'uppercase alphabet A-X' 
            newVal=(charVal-65)+17;       // 'A-X index
         else if ((charVal==89 || charVal==90)) //'uppercase alpha A-Z'
            newVal=(charVal-89)+15;
         else if ((charVal>=97) && (charVal<=120)) //'uppercase alphabet A-X' 
            newVal=(charVal-97)+17;       // 'A-X index
         else if ((charVal==121 || charVal==122)) //'uppercase alpha A-Z'
            newVal=(charVal-121)+15;
         else
            newVal=42;
         newText[lp]=newVal;
     }
     
     return newText;
}
     
